이것은 인터랙티브 노트북입니다. 로컬에서 실행하거나 아래 링크를 사용할 수 있습니다:

Not Diamond를 사용한 LLM 프롬프트 커스텀 라우팅

이 노트북은 Weave를 다음과 함께 사용하는 방법을 보여줍니다 Not Diamond의 커스텀 라우팅 평가 결과를 기반으로 LLM 프롬프트를 가장 적합한 모델로 라우팅합니다.

프롬프트 라우팅

복잡한 LLM 워크플로우를 구축할 때 사용자는 정확도, 비용 또는 호출 지연 시간에 따라 다른 모델에 프롬프트를 보내야 할 수 있습니다. 사용자는 Not Diamond를 사용하여 이러한 워크플로우에서 프롬프트를 필요에 맞는 적절한 모델로 라우팅하여 정확도를 최대화하면서 모델 비용을 절감할 수 있습니다. 어떤 데이터 분포에서도 단일 모델이 모든 쿼리에서 다른 모든 모델보다 우수한 성능을 보이는 경우는 드뭅니다. 여러 모델을 결합하여 각 LLM을 언제 호출할지 학습하는 “메타 모델”을 만들면 개별 모델의 성능을 능가하고 비용과 지연 시간까지 줄일 수 있습니다.

커스텀 라우팅

프롬프트용 커스텀 라우터를 훈련시키려면 세 가지가 필요합니다:
  1. LLM 프롬프트 세트: 프롬프트는 문자열이어야 하며 애플리케이션에서 사용되는 프롬프트를 대표해야 합니다.
  2. LLM 응답: 각 입력에 대한 후보 LLM의 응답입니다. 후보 LLM에는 지원되는 LLM과 사용자 정의 모델이 모두 포함될 수 있습니다.
  3. 후보 LLM의 입력에 대한 응답 평가 점수: 점수는 숫자이며, 필요에 맞는 어떤 메트릭이든 될 수 있습니다.
이러한 항목을 Not Diamond API에 제출하면 각 워크플로우에 맞게 조정된 커스텀 라우터를 훈련시킬 수 있습니다.

훈련 데이터 설정

실제로는 자체 평가를 사용하여 커스텀 라우터를 훈련시킬 것입니다. 그러나 이 예제 노트북에서는 the HumanEval 데이터셋에 대한 LLM 응답을 사용하여 코딩 작업을 위한 커스텀 라우터를 훈련시킬 것입니다. 먼저 이 예제를 위해 준비한 데이터셋을 다운로드한 다음, 각 모델에 대한 LLM 응답을 EvaluationResults로 파싱합니다.
!curl -L "https://drive.google.com/uc?export=download&id=1q1zNZHioy9B7M-WRjsJPkfvFosfaHX38" -o humaneval.csv
python
import random

import weave
from weave.flow.dataset import Dataset
from weave.flow.eval import EvaluationResults
from weave.integrations.notdiamond.util import get_model_evals

pct_train = 0.8
pct_test = 1 - pct_train

# In practice, you will build an Evaluation on your dataset and call
# `evaluation.get_eval_results(model)`
model_evals = get_model_evals("./humaneval.csv")
model_train = {}
model_test = {}
for model, evaluation_results in model_evals.items():
    n_results = len(evaluation_results.rows)
    all_idxs = list(range(n_results))
    train_idxs = random.sample(all_idxs, k=int(n_results * pct_train))
    test_idxs = [idx for idx in all_idxs if idx not in train_idxs]

    model_train[model] = EvaluationResults(
        rows=weave.Table([evaluation_results.rows[idx] for idx in train_idxs])
    )
    model_test[model] = Dataset(
        rows=weave.Table([evaluation_results.rows[idx] for idx in test_idxs])
    )
    print(
        f"Found {len(train_idxs)} train rows and {len(test_idxs)} test rows for {model}."
    )

커스텀 라우터 훈련

이제 EvaluationResults가 있으므로 커스텀 라우터를 훈련시킬 수 있습니다. 계정 생성 API 키 생성을 확인한 다음, 아래에 API 키를 입력하세요. Create an API key
import os

from weave.integrations.notdiamond.custom_router import train_router

api_key = os.getenv("NOTDIAMOND_API_KEY", "<YOUR_API_KEY>")

preference_id = train_router(
    model_evals=model_train,
    prompt_column="prompt",
    response_column="actual",
    language="en",
    maximize=True,
    api_key=api_key,
    # Leave this commented out to train your first custom router
    # Uncomment this to retrain your custom router in place
    # preference_id=preference_id,
)
Not Diamond 앱을 통해 커스텀 라우터의 훈련 과정을 따라갈 수 있습니다. Check on router training progress 커스텀 라우터 훈련이 완료되면 프롬프트를 라우팅하는 데 사용할 수 있습니다.
from notdiamond import NotDiamond

import weave

weave.init("notdiamond-quickstart")

llm_configs = [
    "anthropic/claude-3-5-sonnet-20240620",
    "openai/gpt-4o-2024-05-13",
    "google/gemini-1.5-pro-latest",
    "openai/gpt-4-turbo-2024-04-09",
    "anthropic/claude-3-opus-20240229",
]
client = NotDiamond(api_key=api_key, llm_configs=llm_configs)

new_prompt = (
    """
You are a helpful coding assistant. Using the provided function signature, write the implementation for the function
in Python. Write only the function. Do not include any other text.

from typing import List

def has_close_elements(numbers: List[float], threshold: float) -> bool:
    """
    """ Check if in given list of numbers, are any two numbers closer to each other than
    given threshold.
    >>> has_close_elements([1.0, 2.0, 3.0], 0.5)
    False
    >>> has_close_elements([1.0, 2.8, 3.0, 4.0, 5.0, 2.0], 0.3)
    True
    """
    """
"""
)
session_id, routing_target_model = client.model_select(
    messages=[{"role": "user", "content": new_prompt}],
    preference_id=preference_id,
)

print(f"Session ID: {session_id}")
print(f"Target Model: {routing_target_model}")
이 예제는 또한 Not Diamond의 Weave 자동 추적 호환성을 사용했습니다. Weave UI에서 결과를 확인할 수 있습니다. Weave UI for custom routing

커스텀 라우터 평가

커스텀 라우터를 훈련시킨 후에는 다음을 평가할 수 있습니다
  • 훈련 프롬프트를 제출하여 샘플 내 성능을 평가하거나,
  • 새로운 프롬프트나 보류된 프롬프트를 제출하여 샘플 외 성능을 평가
아래에서는 테스트 세트를 커스텀 라우터에 제출하여 성능을 평가합니다.
from weave.integrations.notdiamond.custom_router import evaluate_router

eval_prompt_column = "prompt"
eval_response_column = "actual"

best_provider_model, nd_model = evaluate_router(
    model_datasets=model_test,
    prompt_column=eval_prompt_column,
    response_column=eval_response_column,
    api_key=api_key,
    preference_id=preference_id,
)
python
@weave.op()
def is_correct(score: int, output: dict) -> dict:
    # We hack score, since we already have model responses
    return {"correct": score}

best_provider_eval = weave.Evaluation(
    dataset=best_provider_model.model_results.to_dict(orient="records"),
    scorers=[is_correct],
)
await best_provider_eval.evaluate(best_provider_model)

nd_eval = weave.Evaluation(
    dataset=nd_model.model_results.to_dict(orient="records"), scorers=[is_correct]
)
await nd_eval.evaluate(nd_model)
이 경우, Not Diamond “메타 모델”은 여러 다른 모델에 걸쳐 프롬프트를 라우팅합니다. Weave를 통해 커스텀 라우터를 훈련시키면 평가도 실행되고 결과가 Weave UI에 업로드됩니다. 커스텀 라우터 프로세스가 완료되면 Weave UI에서 결과를 검토할 수 있습니다. UI에서 Not Diamond “메타 모델”이 프롬프트를 정확하게 답변할 가능성이 더 높은 다른 모델로 라우팅하여 최고 성능 모델보다 더 나은 성능을 보이는 것을 확인할 수 있습니다. Evaluating Not Diamond